package threads;

import java.io.File;
import java.util.List;
import java.util.Random;
import model.*;
import supermarket.DBmanager;
import supermarket.PurchaseXMLManager;

public class ThreadManager {

    private DBmanager db;
    // Πίνακας με τα threads
    private PurchaseThread[] threads;
    // Αριθμός ταυτόχρονων threads
    private int availablePositions = 2;

    public ThreadManager(DBmanager db, int numOfThreads) {
        this.db = db;
        threads = new PurchaseThread[numOfThreads];

        // Δημιούργησε τα νήματα, με διαφορετικό πελάτη στο καθένα
        Random r = new Random();
        Customer c = null;
        // Πάρε όλους τους πελάτες από την Βάση Δεδομένων
        List<Customer> customers = db.getAllCustomerList();
        // διάλεξε πελάτη, Δημιούργησε νήμα, αφαίρεσε πελάτη από
        // την λίστα για να μήν τον ξαναδιαλέξεις,  damn..
        for (int i = 0; i < threads.length; i++) {

            // Πάρε έναν τυχαίο πελάτη που έχει πιστωτική
            CreditCard cc;
            do {
                int customerIndex = r.nextInt(customers.size());
                c = customers.get(customerIndex);
                cc = c.getCreditCard();
            } while (cc == null);

            // Δημιούργησε το νήμα
            threads[i] = new PurchaseThread(db, this, c);
            // Απόδοση ονόματος στο νήμα
            threads[i].setName("Thread " + i + 1);
            //Αφαίρεσε πελάτη απο την λίστα
            customers.remove(c);
        }
    }

    public void populateCustomerBasket() {
        for (int i = 0; i < threads.length; i++) {
            threads[i].populateBasketCart();
        }
    }

    public void startAllThreads() {
        for (int i = 0; i < threads.length; i++) {
            threads[i].start();
        }
    }

    // Περίμενε τα νήματα να τελειώσουν
    public void terminateThreads() {
        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }
        }
    }

    // Ελέγχει αν υπάρχουν ελεύθερες θέσεις
    public boolean hasAvailablePositions() {
        return (availablePositions > 0);
    }

    // Αυξάνει τον αριθμό των ελεύθερων θέσεων
    public void increaseAvailablePositions() {
        availablePositions++;
    }

    // Μειώνει τον αριθμό των ελεύθερων θέσεων
    public void reduceAvailablePositions() {
        availablePositions--;
    }

    // Επιτυχημένα νήματα
    public int getSubmittedNum() {
        int count = 0;
        for (int i = 0; i < threads.length; i++) {
            if (threads[i].isSubmitted()) {
                count++;
            }
        }
        return count;
    }

    // Αποτυχημένα νήματα
    public int getNotSubmittedNum() {
        int count = 0;
        for (int i = 0; i < threads.length; i++) {
            if (!threads[i].isSubmitted()) {
                count++;
            }
        }
        return count;
    }

    // Φτιάξε το XML
    public void writeXMLFile() {

        File xmlFile = new File("purchases.xml");
        PurchaseXMLManager purchaseXMLWriter = new PurchaseXMLManager(xmlFile);
        for (int i = 0; i < threads.length; i++) {
            purchaseXMLWriter.writeXML(threads[i]);
        }

    }
}
